perm filename EDITOR.F79[206,LSP] blob
sn#476798 filedate 1979-09-24 generic text, type C, neo UTF8
COMMENT ⊗ VALID 00005 PAGES
C REC PAGE DESCRIPTION
C00001 00001
C00002 00002 .s(EDITOR,THE LISP EDITOR)
C00004 00003 .ss(commands, LISP Editor commands.)
C00015 00004 .ss(editorex,Example session with the LISP Editor.)
C00018 00005 .bb Constructing a program using the editor.
C00021 ENDMK
C⊗;
.s(EDITOR,THE LISP EDITOR)
The LISP Editor was written by R.P.Gabriel and T.Finin.
It is a structural editor that runs in the MACLISP interpreter.
The editor is useful for modifying programs already defined,
for constructing a program from scratch, or for editing other
expressions, or properties. The editor assumes that the
expressions it is dealing with are hierarchical list structures,
e. g. lists whose elements are either atoms or other lists.
The editor knows about a top level expression and a current
expression (CE) which is a subexpression of the top level expression.
Initially they are the same. (Proceed at your own
risk if you try to edit a random S-expression.)
Among the possible operations are:
change the CE, add, or delete elements of the CE,
move parentheses in and out to change the subexpression
structure, or change the CE by moving up, down or sideways
within the toplevel expression. It is also possible to move around
in the expression by searching a match to a pattern.
The documentation that follows is largley taken from the
online documentation of the LISP editor at the
Stanford University AI Lab.
.ss(commands, LISP Editor commands.)
.cb Invoking the Editor
There are various ways to invoke the editor corresponding to
different ways of forming the top level expression to be edited.
.begin indent 0,4 turnon "∂"
1). ∂(4)(EDIT FOO) edit the in-core function "FOO" . The top level
expression becomes (DEFUN FOO <bvars> <body>), if the EXPR
property of FOO is (LAMBDA <bvars> <body>).
2). ∂(4)(EDIT1 <exp>) will make <exp> the toplevel editable expression.
3). ∂(4)(EDIT2 <var>) will make (PROG2 (SETQ <var> <current value of var>) T)
the toplevel while (EDIT2 (GET <var> <indicator>)) will make it:
(DEFPROP <var> <value> <indicator>).
.end
.cb |How to Look at the Current Expression (CE)|
.begin turnon "∂"
.n←16
.indent 0,8
P∂(n) prints the CE using the current print depth
(sublist cutoff) and print length (length cutoff)
PP∂(n) pretty-prints the entire CE
PS∂(n) pretty-prints the CE using the print depth cutoff
W∂(n) prints the "window" surrounding the CE. Thus if
window size is 2, it prints the 2 preceeding and 2 following
tokens around the CE, where "token" means expression or
parenthesis.
(WINDOW n)∂(n) changes the window size to n.
(PL n)∂(n) changes the print length to n (initially 5)
(PD n)∂(n) changes the print depth to n (initially 2)
.end
.cb Changing the CE
.begin turnon "∂"
.n←16
.indent 0,8
(CR E1...En)∂(n) changes the CE to E1...En (i.e. splices in E1...En,
and makes the CE E1.
(n E1...En)∂(n) n>0, changes the n-th element of the CE to E1...En
(n E1...En)∂(n) n<0 changes the n-th element of the CE from the end to E1...En
(n)∂(n) n>0 deletes the n-th element of the CE
(n)∂(n) n<0, deletes the n-th element from the end
RI∂(n) moves the right parenthesis in one expression
RO∂(n) moves the right parenthesis out one expression
LI∂(n) similar to RI
LO∂(n) similar to RO
DELETE∂(n) deletes the CE (if the CE is the toplevel expression,
the Editor assumes that the user wants to edit a different function and requests:
.end
(function name <file specifications>):
Valid responses are:
.begin nofill indent 4,4
1) FOO - loads FOO from core
4) NEW - gives a fresh top-level expression
5) cntrl-G - quits back to the Editor command decoder
6) UNDO - <see below>.
.end
[Note: the Editor is designed to be able to get definitions from files,
but the current editor is incompatible with NEWIO in the current version
of MACLISP.]
.cb Moving around within the Expression
.begin turnon "∂" nofill
.n←16
n∂(n)n>0 makes the new CE the n-th element of the CE
n∂(n)n<0, makes the new CE the n-th element from the end of the CE
↑∂(n)makes the CE the immediate parent of the CE
TOP∂(n)makes the CE the toplevel expression
NX∂(n)makes the CE the next one after the CE
BK∂(n)makes the CE the one before the CE
.end
.cb Adding Expressions
.begin turnon "∂" nofill
.n←16
(A n E1...En)∂(n) puts E1...En after the n-th element of the CE
(B n E1...En)∂(n) puts E1...En before the n-th element of the CE
(AI E1...En)∂(n) puts E1...En after the CE and makes E1 the new CE
(BI E1...En)∂(n) puts E1...En before the CE and makes E1 the new CE
(R exp1 exp2)∂(n) replaces all occurrences of exp1 with exp2 in the CE, viewed as a list,
∂(n) returns nil? if no occurrences found
(TR exp1 exp2)∂(n)replaces all occurrences of exp1 with exp2 in the CE, viewed as a tree
.end
.cb |Finding Expressions (i.e. changing the CE)|
.begin turnon "∂" nofill
.n←16
(F pat)∂(n) finds the next occurrence of pat, searching in print order
(BF pat)∂(n)finds the next occurrence of pat, searching in inverse print order
(F pat T)∂(n)finds the next occurrence of pat but looks at the topmost elements
∂(n)of the CE first (useful for getting to PROG tags)
(BF pat T)∂(n) similar to above
(F pat n)∂(n) finds the n-th occurrence of pat
(BF pat n)∂(n) similar to above
F∂(n) finds the next occurrence of the last search pattern
BF∂(n) similar to above
.end
Pat, as used above, can contain any of the following:
.cb Patterns
.begin nofill turnon "∂"
.n←24
Element of pat ∂(n) What it matches
------- -- --- ∂(n) ---- -- -------
atom ∂(n) atoms EQ to it
list ∂(n) calls matcher recursively
? ∂(n) any atom or single list (i.e. an s-expression)
?X ∂(n) any element; binds ?X to whatever it matched
* ∂(n) any non-empty string of elements
*X ∂(n) matches as *, but binds *X to the list of elements it matched
=?X ∂(n) whatever ?X matched last time
=*X ∂(n) whatever *X matched last time
(RESTRICT ? P1...Pn) ∂(n)any element satisfying the predicates P1,...,Pn
(RESTRICT ?X P1...Pn) ∂(n)similar to above but binds ?X to what it matched.
.end
[Note: (A ?X IS A ?X) matches (a word is a word) but not (a word is a sentence).
Simlarly for (*X is a *X).]
.cb Invoking the Matcher
.begin nofill turnon "∂"
.n←16
(MATCH pat)∂(n)attempts to match pat against the CE
(MATCH pat var1 ... varn)
∂(n) attempts to match pat against the CE while retaining the
∂(n) values of the variables var1,..., varn.
∂(n) (E.g. (MATCH (* *A *B ?A) *A ?A).
MATCH∂(n)attempts to match the last pat against the CE. Like F and BF above.
REMATCH∂(n)attempts to get the next match of pat against the CE.
∂(n) Usually this only makes sense if pat contains some * variables.
(REMATCH var1 ... varn)
∂(n) rematches but will retain var1,...,varn.
.end
.cb Hairy Matching Uses
.begin nofill turnon "∂"
.n←16
(PR pat)∂(n)replaces the CE with the instantiation of pat
∂(n)(substitutes the values of ?-variables and *-variables)
(PA n P1...Pn)∂(n) similar to (A n E1...En)
(PB n P1...Pn)∂(n) similar to (B n E1...En)
(PAI P1...Pn)∂(n) similar to (AI E1...En)
(PRA exp1 pat)∂(n) similar to (R exp1 exp2)
(TPRA exp1 pat)∂(n) similar to (TR exp1 exp2)
.end
.cb Exiting and Etc.
.begin nofill turnon "∂"
.n←16
REMEMBER∂(n)puts the toplevel expression under the "draft" property
∂(n)(preserves DEFUN format and comments)
OK∂(n)REMEMBER's and EVAL's the toplevel expression
∂(n)(i.e. defines the function as well as remembers it)
EXIT exits the Editor (to the LISP toplevel)
.end
.cb None of the above.
Any other command is handed to LISP to be EVAL'ed.
.next page
.ss(editorex,Example session with the LISP Editor.)
Here are some things you can do using the LISP Editor.
The user types in lower case, LISP replys in upper case, ";;;"
flags a user comment, ";" a LISP comment.
← is the editor prompt. It begins a command line. Several commands
may appear on a line. The editor processes them sequentially.
Refer to the above documentation if you don't remember what the commands
are supposed to do.
# is used to denote structure not shown when printing the skeleton of
an S-expression.
.bb Modifying an existing program
.begin "edit session 1"
.verbatim
.select 6
;;; Modify APPEND to test for atoms in general not just NIL.
;;; Assume that APPEND has been DEFUNed already.
(edit append)
;loading EDIT.110
;LOADING GRIND 412
RPG-EDIT
← pp
;Loading GRINDEF 425
(DEFUN APPEND (U V)
(COND ((NULL U) V) (T (CONS (CAR U) (APPEND (CDR U) V)))))
← (f null) (cr atom) p
ATOM
← ↑ p
(ATOM U)
← ↑ p
((ATOM U) V)
← bk p
COND
← ↑ p
(COND (# V) (T #))
← bk p
(U V)
← (1 x) p
(X V)
← nx p
(COND (# V) (T #))
← (r u x) pp
(COND ((ATOM X) V) (T (CONS (CAR X) (APPEND (CDR X) V))))
← top p
(DEFUN APPEND (X V) (COND # #))
← (r append appx) pp
(DEFUN APPX (X V)
(COND ((ATOM X) V) (T (CONS (CAR X) (APPX (CDR X) V)))))
← ok
APPX
;;;Any expression not recognized as an edit command will be EVALed
← (appx 'a ())
NIL
← (appx '(a . b) '(c))
(A C)
← (appx '(a b . c) 'c)
(A B . C)
;;; Some alternate ways to invoke the Editor
← (setq u '(a b c d))
(A B C D)
← (edit1 u) p
(A B C D)
← (edit2 u) pp
(PROG2 (SETQ U '(A B C D)) T)
.end "edit session 1"
.next page
.bb Constructing a program using the editor.
.begin "edit session 2"
.verbatim
.select 6
;;; Construct the program SUBST (see section I.)
← (edit2 (get subst expr)) pp ;;; First define the empty program
(DEFPROP SUBST NIL EXPR)
← (3 (lambda (x y z) (cond ()())) ) p ;;; Replace by a skeleton
(DEFPROP SUBST (LAMBDA # #) EXPR)
← 3 p
(LAMBDA (X Y Z) (COND NIL NIL))
← 3 2 (b 1 (atom z) ()) p ;;; Partially fill in first clause
((ATOM Z) NIL) ;;; of the conditional.
← 2 (cr (cond ()())) p ;;; The skeleton of the value part
(COND NIL NIL)
← (2 ((eq y z) x)) p
(COND (# X) NIL)
← (a 2 t z) p
(COND (# X) T Z NIL)
← 5 lo lo p
(T Z)
← ↑ ↑ pp
((ATOM Z) (COND ((EQ Y Z) X) (T Z)))
← nx p ;;; Go to second clause.
NIL
← (cr (t (cons (subst) (subst)))) p ;;; Partially fill in 2nd clause
(T (CONS # #))
← 2 (a 2 x y (car x)) 2 ro ro ro pp ;;; Fill in arguments once
(SUBST X Y (CAR X))
← 4 (2 z) p ;;; correct the mistake
(CAR Z)
← nx
nil? ;;; there is no next expression
← ↑ nx p
(SUBST)
← (a 1 x y (cdr z)) p ;;; Fill in arguments again
(SUBST X Y (CDR Z))
← ↑ pp
(CONS (SUBST X Y (CAR Z)) (SUBST X Y (CDR Z)))
← top pp ;;; Now to view our work
(DEFPROP SUBST
(LAMBDA (X Y Z)
(COND ((ATOM Z) (COND ((EQ Y Z) X) (T Z)))
(T (CONS (SUBST X Y (CAR Z)) (SUBST X Y (CDR Z))))))
EXPR)
← ok ;;; make this the official definition
SUBST
;;; Try it out
← (subst ''(a . b) 'x '(cons (car x) (cdr x)))
(CONS (CAR (QUOTE (A . B))) (CDR (QUOTE (A . B))))
← (eval (subst ''(a . b) 'x '(cons (car x) (cdr x))))
(A . B)
.end "edit session 2"